/* components */
import { 
  SettingGPTViewDialog,
  SettingGPTViewContentTitle,
  SettingGPTViewContentSubTitle,
  SettingGPTViewCheckbox,
  SettingGPTViewCheckboxGroup
} from "@src/modules/setting/gpt/components"
import SettingGPTEditViewModuleAdd from "@src/modules/setting/gpt/views/edit/module-add"
/* enum */
import ComponentNameEnum from '@model/enum/ComponentNameEnum'
/* model */
import { SettingGPTRobotInsideModules, SettingGPTRobotInsideModuleWiki } from "@src/modules/setting/gpt/model"
/* vue */
import { defineComponent, PropType } from 'vue'
/* types */
import { SettingGPTRobotModuleConfigType, SettingGPTRobotModuleType } from "@src/modules/setting/gpt/types"
/* util */
import { cloneDeep, isEmpty, isFalsy } from "@src/util/type"
import { message } from "@src/util/message"

type SettingGPTViewDialogComponentType = InstanceType<typeof SettingGPTViewDialog>
type SettingGPTEditViewModuleAddComponentType = InstanceType<typeof SettingGPTEditViewModuleAdd>

enum SettingGPTEditViewModuleMixinEventEnum {
  Input = 'input'
}

export default defineComponent({
  name: ComponentNameEnum.SettingGPTEditViewModuleMixin,
  props: {
    allModules: {
      type: Array as PropType<SettingGPTRobotModuleType[]>,
      default: () => []
    },
    value: {
      type: Object as PropType<SettingGPTRobotModuleConfigType>,
      default: () => ({})
    },
    wikiValue: {
      type: Array as PropType<string[]>,
      default: () => []
    },
    onInput: {
      type: Function
    }
  },
  data() {
    return {
      selectValueList: [] as string[]
    }
  },
  computed: {
    title(): string {
      return ''
    },
    subTitle(): string {
      return ''
    },
    allowAddModuleList(): SettingGPTRobotModuleType[] {
      return this.allModules.filter(item => {
        return isFalsy(this.showModuleValueList.includes(item.value))
      })
    },
    disabled(): boolean {
      return Boolean(this.value.disabled)
    },
    enable(): boolean {
      return Boolean(this.value.enable)
    },
    allModulesMap(): Record<string, SettingGPTRobotModuleType> {
      return this.allModules.reduce((result, item) => {
        result[item.value] = item
        return result
      }, {} as Record<string, SettingGPTRobotModuleType>)
    },
    enableModuleList(): SettingGPTRobotModuleType[] {
      return this.modules.filter(item => Boolean(item?.enable))
    },
    enableModuleValueList(): string[] {
      return this.enableModuleList.map(item => item.value)
    },
    modules(): SettingGPTRobotModuleType[] {
      return this.value.modules || []
    },
    showModuleList(): SettingGPTRobotModuleType[] {
      return this.modules.filter(item => Boolean(item?.show))
    },
    showModuleValueList(): string[] {
      return this.showModuleList.map(item => item.value)
    },
    settingGPTViewDialogComponent(): SettingGPTViewDialogComponentType {
      return this.$refs.SettingGPTViewDialog as SettingGPTViewDialogComponentType
    },
    settingGPTEditViewModuleAddComponent(): SettingGPTEditViewModuleAddComponentType {
      return this.$refs.SettingGPTEditViewModuleAdd as SettingGPTEditViewModuleAddComponentType
    }
  },
  methods: {
    closeDialog() {
      this.settingGPTViewDialogComponent.close()
    },
    clearSelectValueList() {
      this.settingGPTEditViewModuleAddComponent.clear()
    },
    /** 
     * @description 打开弹窗
    */
    openDialog() {
      this.settingGPTViewDialogComponent.open()
    },
    /**
     * @description 点击添加更多事件
     */
    onAddModuleHandler() {
      throw new Error('onAddModuleHandler is not implemented')
    },
    /**
     * @description 开关切换事件
    */
    onSwitchChangeHandler(value: boolean) {
      
      const newValue = {
        ...this.value,
        enable: value
      }
      
      this.$emit(SettingGPTEditViewModuleMixinEventEnum.Input, newValue)
      
    },
    onAddMoreSelectValueListChangeHandler(valueList: string[]) {
      this.selectValueList = valueList
    },
    onModuleListChangeHandler(valueList: string[]) {
      
      const newModules = cloneDeep(this.modules).map((item: SettingGPTRobotModuleType) => {
        item.enable = valueList.includes(item.value)
        return item
      })
      
      const newValue = {
        ...this.value,
        modules: newModules
      }
      
      this.$emit(SettingGPTEditViewModuleMixinEventEnum.Input, newValue)
      
    },
    onAddMoreConfirmHandler() {
      
      if (isEmpty(this.selectValueList)) {
        message.warning('请选择')
        return
      }
      
      const addedModules = this.allModules.filter(item => {
        return this.selectValueList.includes(item.value)
      })
      
      const addedShowModules = cloneDeep(addedModules).map((item: SettingGPTRobotModuleType) => {
        item.show = true
        return item
      })
      
      const newValue = {
        ...this.value,
        modules: [
          ...this.modules,
          ...addedShowModules
        ]
      }
      
      this.$emit(SettingGPTEditViewModuleMixinEventEnum.Input, newValue)
      
      this.closeDialog()
      
      this.clearSelectValueList()
      
    },
    onSettingClickHandler(value: string) {
      // 知识库
      if (value === SettingGPTRobotInsideModuleWiki.value) {
        this.onSettingWikiClickHandler()
      }
    },
    onSettingWikiClickHandler() {
      throw new Error('onSettingWikiClickHandler is not implemented')
    },
    /** 
     * @description 渲染开关
    */
    renderSwitch() {
      return (
        <el-switch
          disabled={this.disabled}
          value={this.enable}
          onChange={this.onSwitchChangeHandler}
        >
        </el-switch>
      )
    },
    renderAddMoreCheckbox() {
      return (
        <SettingGPTViewCheckbox
          disabled
          onClick={this.onAddModuleHandler}
        >
          + 添加更多
        </SettingGPTViewCheckbox>
      )
    },
    renderTitle() {
      return (
        <SettingGPTViewContentTitle
          title={this.title}
        >
        </SettingGPTViewContentTitle>
      )
    },
    renderSubTitle() {
      return (
        <SettingGPTViewContentSubTitle
          title={this.subTitle}
        >
        </SettingGPTViewContentSubTitle>
      )
    },
    renderSubTitleWithSwitch() {
      return (
        <div class="setting-gpt-edit-view-content-common-switch-block">
          { this.renderSwitch() }
          { this.renderSubTitle() }
        </div>
      )
    },
    renderCheckboxContent(item: SettingGPTRobotModuleType) {
      
      const value = item.value
      const showSetting = Boolean(this.allModulesMap[value]?.showSetting)
      
      const onSettingClick = (event: Event) => {
        if (showSetting) {
          event?.stopPropagation()
          this.onSettingClickHandler(value)
        }
      }
      
      let setting
      
      if (showSetting) {
        setting = (
          <div 
            class="setting-gpt-edit-view-content-common-checkbox-setting"
            onClick={onSettingClick}
          >
            <i class="iconfont icon-xitongguanli"></i>
          </div>
        )
      }
      
      if (isFalsy(item.disabled)) {
        return (
          <div class="setting-gpt-edit-view-content-common-checkbox-content">
            <span>
              { item.name }
            </span>
            { setting }
          </div>
        )
      }
      
      return (
        <el-tooltip
          effect="dark"
          content="暂未开放，敬请期待"
          placement="top"
        >
          <span>{ item.name }</span>
        </el-tooltip>
      )
      
    },
    renderCheckboxGroup(multiple: boolean = true) {
      return (
        <SettingGPTViewCheckboxGroup
          v-show={this.enable}
          multiple={multiple}
          value={this.enableModuleValueList}
          onChange={this.onModuleListChangeHandler}
        >
          
          {this.showModuleList.map(item => {
            return (
              <SettingGPTViewCheckbox
                label={item.value}
                disabled={item.disabled}
              >
                { this.renderCheckboxContent(item) }
              </SettingGPTViewCheckbox>
            )
          })}
          
          { this.renderAddMoreCheckbox() }
          
        </SettingGPTViewCheckboxGroup>
      )
    }
  }
})